import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime
from utils.log import Logger


plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['font.size'] = 15


class DataAnalysis(object):
    def __init__(self, path):
        logfile_name = "data_analysis_" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
        self.logger = Logger("../", logfile_name).get_logger()
        self.logger.info('data_analysis开始')
        data = pd.read_csv(path)
        self.datas = data


def data_analysis(ana_datas):
    # 四个图排成一列（2行2列），推荐尺寸(12, 24)
    fig = plt.figure(figsize=(24, 12))  # 宽度12，高度24，适合4个子图垂直排列

    # 第1个子图：各年龄段员工流失率趋势（折线图）
    ax1 = fig.add_subplot(224)  # 4行1列的第1个位置
    age_attrition = ana_datas.groupby('Age')['Attrition'].agg(
        总人数='count',
        流失人数=lambda x: (x == 1).sum()
    ).reset_index()
    # print(age_attrition)

    age_attrition['流失率'] = (age_attrition['流失人数'] / age_attrition['总人数'] * 100).round(2)
    age_attrition = age_attrition.sort_values('Age')
    # print(age_attrition)
    # sns.lineplot(
    #     data=age_attrition,
    #     x='Age',
    #     y='流失率',
    #     marker='o',
    #     linewidth=2,
    #     markersize=6,
    #     ax=ax1  # 指定子图
    # )
    ana_datas.info()
    ax1.plot(age_attrition['Age'],
             age_attrition['流失率'],
             marker='o',
             linewidth=2,
             markersize=6
             )
    ax1.set_title('离职率 vs 年龄', fontsize=16, pad=10)
    ax1.set_xlabel('年龄', fontsize=12)
    ax1.set_ylabel('离职率 (%)', fontsize=12)
    ax1.grid(linestyle='--', alpha=0.7)

    # 第2个子图：工作级别离职率（柱状图，假设5个级别）
    ax2 = fig.add_subplot(222)  # 4行1列的第2个位置
    job_attrition = ana_datas.groupby('JobLevel')['Attrition'].agg(
        总人数='count',
        离职人数=lambda x: (x == 1).sum()
    ).reset_index()
    # print(job_attrition)
    # 求出离职率 ，并添加一列，round(2)保留25位小数
    job_attrition['离职率(%)'] = (job_attrition['离职人数'] / job_attrition['总人数'] * 100).round(2)
    job_attrition = job_attrition.sort_values('JobLevel')
    # print(job_attrition)
    # sns.barplot(
    #     data=job_attrition,
    #     x='JobLevel',
    #     y='离职率(%)',
    #     hue='JobLevel',
    #     palette='plasma',
    #     edgecolor='black',
    #     legend=False,
    #     ax=ax2  # 指定子图
    # )
    x = job_attrition['JobLevel']  # 横坐标：岗位等级
    y = job_attrition['离职率(%)']  # 纵坐标：离职百分比

    # 2. 画柱状图
    ax2 = plt.gca()  # 或者 fig, ax2 = plt.subplots()
    bars = ax2.bar(x, y,
                   color=['skyblue', 'orange', 'tomato', 'red', 'blue'],  # 同 sns 的 palette='plasma'
                   edgecolor='black')
    ax2.set_title('各工作级别员工离职率', fontsize=16, pad=10)
    ax2.set_xlabel('工作级别', fontsize=12)
    ax2.set_ylabel('离职率 (%)', fontsize=12)
    ax2.grid(axis='y', linestyle='--', alpha=0.7)

    # 第3个子图：示例图（可替换为你的第三个指标）
    ax3 = fig.add_subplot(223)  # 4行1列的第3个位置
    # 1. 按出差频率分组，计算离职率均值
    business_travel_attrition = ana_datas.groupby('BusinessTravel')['Attrition'].mean()

    # 2. 定义“原始值 → 自定义标签”的映射关系
    label_mapping = {
        'Non-Travel': '出差少',
        'Travel_Rarely': '出差中等',
        'Travel_Frequently': '出差多'
    }

    # 3. 对离职率**升序排序**，确保柱状图按“离职率从低到高”排列
    sorted_attrition = business_travel_attrition.sort_values()
    # 4. 生成自定义X轴标签（与排序后的顺序对应）
    custom_labels = [label_mapping[idx] for idx in sorted_attrition.index]
    # 5. 绘制柱状图（用range控制x轴位置，避免原始分类顺序干扰）
    ax3.bar(
        range(len(sorted_attrition)),  # x轴位置（0,1,2...）
        sorted_attrition.values,  # 离职率数值
        color=['skyblue', 'orange', 'tomato']
    )

    # 6. 替换X轴刻度为自定义标签
    ax3.set_xticks(range(len(sorted_attrition)))
    ax3.set_xticklabels(custom_labels)

    # 7. 设置轴标签与标题
    ax3.set_ylabel('离职率')
    ax3.set_title('出差频率与离职率')
    # ax3.set_xticks(rotation=15)

    # 第4个子图：示例图（可替换为你的第四个指标）
    ax4 = fig.add_subplot(221)  # 4行1列的第4个位置
    # 这里替换为你的第四个图数据和绘图代码
    ax4.set_title('第四个指标分析', fontsize=16, pad=10)
    attr_counts = ana_datas['Attrition'].value_counts().sort_index()  # 0 在前，1 在后
    ax4.bar(['未离职', '离职'],  # x 轴标签
            attr_counts.values,  # 高度
            color=['#1f77b4', '#d62728'])
    ax4.set_ylabel('人数')
    ax4.set_title('员工流失分布')

    # 调整整体布局，避免重叠
    plt.tight_layout()
    plt.subplots_adjust(hspace=0.3)  # 调整子图之间的垂直间距
    plt.savefig('../data/fig/数据分析.png')
    # plt.show()

    # 离家距离与离职率的关系
    # 1. 分段
    bins = np.arange(0, ana_datas['DistanceFromHome'].max() + 10, 10)
    ana_datas['dist_bin'] = pd.cut(ana_datas['DistanceFromHome'], bins, right=False)

    # 2. 计算每段离职率
    rate = ana_datas.groupby('dist_bin')['Attrition'].mean()
    # 3. 画图
    plt.figure(figsize=(15, 8))
    rate.plot(kind='bar', color='steelblue', edgecolor='k')
    plt.xticks(rotation=45)
    plt.ylabel('离职率')
    plt.title('离家距离分段离职率（每10km一组）')
    plt.grid(alpha=0.3, axis='y')
    plt.tight_layout()

    # 曾就职公司数和离职率的关系
    # 1. 按“相同距离值”聚合
    rate = ana_datas.groupby('NumCompaniesWorked', as_index=False)['Attrition'].mean()
    # 2. 排序（横轴从近到远）
    rate = rate.sort_values('NumCompaniesWorked')
    # 3. 折线图
    plt.figure(figsize=(15, 8))
    plt.plot(rate['NumCompaniesWorked'], rate['Attrition'],
             marker='o', color='orangered')
    plt.xlabel('曾就职公司数')
    plt.ylabel('离职率')
    plt.title('曾就职公司数的离职率折线图')
    plt.grid(alpha=0.3)
    plt.tight_layout()

    # 工作等级与月薪的关系
    level_mean = ana_datas.groupby('JobLevel')['MonthlyIncome'].mean()
    plt.figure(figsize=(15, 8))
    # 箱线图
    plt.boxplot([ana_datas[ana_datas['JobLevel'] == lvl]['MonthlyIncome']
                 for lvl in level_mean.index],
                labels=level_mean.index)
    # 均值折线
    plt.plot(range(1, len(level_mean) + 1), level_mean.values,
             color='orangered', marker='o', label='均值')
    plt.legend()
    plt.xlabel('工作等级')
    plt.ylabel('月薪')
    plt.title('工作等级月薪分布与均值趋势')
    plt.tight_layout()
    #
    # 最近涨薪比例和工作绩效的关系

    mean_hike = ana_datas.groupby('PerformanceRating')['PercentSalaryHike'].mean()
    plt.figure(figsize=(5, 3))
    plt.bar(mean_hike.index.astype(str), mean_hike.values,
            color='steelblue', edgecolor='k')
    plt.xlabel('Performance Rating')
    plt.ylabel('平均涨薪比例 (%)')
    plt.title('最近涨薪比例 vs 工作绩效（柱状）')
    plt.grid(alpha=0.3, axis='y')
    for x, y in zip(mean_hike.index, mean_hike.values):
        plt.text(x, y + 0.2, f'{y:.1f}', ha='center', va='bottom')
    plt.tight_layout()
    plt.show()


if __name__ == '__main__':
    da = DataAnalysis("../data/train.csv")
    data_analysis(da.datas)
